package net.qiujuer.genius.blur.frags;

import net.qiujuer.genius.blur.ResourceTable;
import net.qiujuer.genius.blur.utils.PixelMapUtils;
import net.qiujuer.genius.blur.utils.PxUtils;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.PixelMapHolder;
import ohos.agp.render.Texture;
import ohos.agp.utils.Color;
import ohos.agp.utils.Matrix;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;

public abstract class BaseFragment extends StackLayout
        implements Component.ClickedListener {

    protected Text mText;
    protected Text mTime;
    protected boolean isScale = true;
    protected PixelMap mBitmap;

    public BaseFragment(Context context) {
        this(context, null);
    }

    public BaseFragment(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public BaseFragment(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        onCreateView();
    }

    protected void onCreateView() {
        LayoutScatter.getInstance(getContext())
                .parse(ResourceTable.Layout_fragment_blur, this, true);
        mText = (Text) findComponentById(ResourceTable.Id_text);
        mTime = (Text) findComponentById(ResourceTable.Id_time);
        setClickedListener(this);
    }

    public void setBitmap(PixelMap bitmap) {

        mBitmap = PixelMapUtils.createBitmap(getWidth(),
                getHeight(),
                PixelFormat.ARGB_8888);
        Canvas canvas = new Canvas(new Texture(mBitmap));
        canvas.translate(-getLeft(), -getTop());
        canvas.scale(1, 1);
        Paint paint = new Paint();
        paint.setFilterBitmap(true);
        canvas.drawPixelMapHolder(new PixelMapHolder(bitmap), 0, 0, paint);

        //Call Blur
        blur();

    }

    protected PixelMap getScaleBitmap(PixelMap bitmap) {
        float scaleFactor = 5f;
        float scale = 1f / scaleFactor;
        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);
        PixelMap ret = PixelMapUtils.createBitmap(bitmap,
                0,
                0,
                bitmap.getImageInfo().size.width,
                bitmap.getImageInfo().size.height,
                matrix,
                true);
        bitmap.release();
        return ret;
    }

    protected PixelMap getNewBitmap() {
        return PixelMapUtils.createBitmap(mBitmap);
    }

    protected void blur() {
        if (mBitmap == null || mText == null) {
            return;
        }

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                PixelMap bitmap = getNewBitmap();
                int radius = 20;
                if (isScale) {
                    radius = 2;
                    bitmap = getScaleBitmap(bitmap);
                }

                long startTime = System.currentTimeMillis();
                final PixelMap ret = blur(bitmap, radius);
                show(ret, System.currentTimeMillis() - startTime);
            }
        });
        thread.start();
    }

    protected void show(final PixelMap bitmap, final long time) {
        new EventHandler(EventRunner.getMainEventRunner())
                .postTask(new Runnable() {
                    @Override
                    public void run() {
                        PixelMapElement element = new PixelMapElement(bitmap);
                        setBackground(element);
                        show(time);
                    }
                });
    }

    @Override
    public void onClick(Component component) {
        blur();
        isScale = !isScale;
    }

    protected void show(long time) {
        if (mTime != null) {
            mTime.setText(time + "ms");
        }
    }

    protected abstract PixelMap blur(PixelMap bitmap, int radius);
}
